Better Code Step by Step
The Evolution of a Simple Function: Readability, Performance, and the Euphoria Mindset
A beginner's journey from "it works" to "it works well."
Ronald Weidner
Introduction
I want to share something that works. It's not pretty. Honestly, it's kind of ugly. But it works.
When you're starting out, sometimes all you care about is: "Does it work?" If yes, then you're done. Mission complete.
But if you want to level up write code that's clean, fast, and easy to read you've got to ask a few simple questions:
- Can I make this easier to read?
- Can I make it run faster?
- Can I make it smarter?
Let's look at a real example. One simple function gets rewritten a few times. Each version is better in some way until it's not. You'll see what I mean.
Step 1: It Works. That's All
function fixed_len(sequence s, integer len) sequence retval = "" integer i = 1 while (i < length(s) + 1) and (i < len + 1) do retval = sprintf("%s%s", {retval,s[i]}) i += 1 end while while i < len + 1 do retval = sprintf("%s%s", {retval," "}) i += 1 end while return retval end function
What it does:
Make sure the string is exactly 'len' characters long. Builds the string character by character. If it's too short, pad with spaces. If it's too long, chop it.
What's wrong with it?
- It's slow.
- It makes lots of copies with 'sprintf()', which returns a new string each time.
- It's harder to read compared to some alternatives.
But hey! It works. And sometimes, that's enough.
Step 2: A Little Better
function fixed_len(sequence s, integer len) sequence retval = repeat(" ", len) integer i = 1 while i <= length(s) and i <= len do retval[i] = mid(s, i, 1) i+=1 end while return join(retval, "") end function
What improved?
- Pre-allocates the result. It's not rebuilding a string every loop.
- 'mid()' is better than 'sprintf()'. The intent is much clearer.
Still a bit messy:
- 'mid()' returns a one-character sequence.
- We 'join()' it at the end, which feels clunky.
We can do better.
Step 3: Even Cleaner
function fixed_len(sequence s, integer len) sequence retval = repeat(' ', len) integer i = 1 while i <= length(s) and i <= len do retval[i] = s[i] i+=1 end while return retval end function
Why this one is better:
- No 'mid()', no 'join()', no 'sprintf()'.
- Just clean copy logic.
- Faster and easier to follow.
So, should we stop here? Maybe. But let's see if we can do it without a loop.
Step 4: Slick and Fast
function fixed_len(sequence s, integer len) if length(s) < len then return s & repeat(' ', len - length(s)) end if return s[1..len] end function
Why this one's great:
- No loop.
- Just slice and pad.
- Uses built-in operations that are highly optimized.
Performance? Likely the best so far.
Readability? Crystal clear.
Beginner-friendly? If you understand slices and concatenation, yes. Otherwise, it's a good excuse to learn them.
Step 5: Maybe Too Clever?
function fixed_len(sequence s, integer len) return s[1..min(length(s), len)] & repeat(' ', max(0, len - length(s))) end function
It works, probably. But should you write it this way?
Maybe not.
- Cramming logic, math, and manipulation all in one line.
- Clever? Yeah.
- Readable? Maybe not for everyone.
Final Thoughts: Mind Right, Code Tight
When you're just getting started:
- Don't try to be perfect.
- Make it work first.
- Then make it better.
And Remember
- Write clear code for future you and anyone who might follow after.
- Write efficient code by thinking about what the computer actually does with your instructions.
- Clarity almost always wins. Until it doesn't. And when that moment comes, you'll know.
But first? Just make it work.
Not Categorized, Please Help
|